home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d13 / ptv2n1.arc / PREFERS.ASM < prev    next >
Assembly Source File  |  1991-03-26  |  15KB  |  350 lines

  1.        TITLE PREFERS.SYS - Sample Device Driver
  2.        PAGE 60,132
  3. ;=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  4. ;                     P R E F E R S . S Y S
  5. ;       By George W. Seaton -- Assemble with Borland's TASM
  6. ;
  7. ; This module is an example of a simple "character" device driver.
  8. ; It does not "drive" any particular device; instead, it sets up
  9. ; certain BIOS parameters for the video and keyboard, according
  10. ; to the user's personal preferences.  For the author's AT-clone
  11. ; with an EGA color video, these preferences include:
  12. ;
  13. ;  - Turning off the NumLock state.
  14. ;  - Setting the EGA video to 43-line mode.
  15. ;  - Turning OFF the video blink bit.
  16. ;
  17. ; After its initial installation, users can use the driver (i.e.,
  18. ; by writing to the device) to toggle these parameters.
  19. ;================================================================
  20. ; Assembler setup commands
  21. ;================================================================
  22. CSEG   Segment byte public "CODE"
  23.        Assume CS:CSEG,DS:CSEG,ES:CSEG
  24.        Org 00H                ;<============ NOTE!
  25. PREFERS:
  26. ;================================================================
  27. ;             D R I V E R   H E A D E R   B L O C K
  28. ;
  29. ; Bytes 0000h-0011h of the driver M-U-S-T be set up as follows:
  30. ;================================================================
  31.        DW     0FFFFh          ;+0: Offset of next Device (if any)
  32.        DW     0FFFFh          ;+2: Segment of next Device (if any)
  33. ;----------------------------------------------------------------
  34.        DW     8000h           ;+4: Device Attribute Word
  35. ;                             (Bit 15 SET for "Character" device)
  36. ;----------------------------------------------------------------
  37.        DW     Offset STRAT    ;+6: Offset of "Strategy" routine
  38.        DW     Offset INTRPT   ;+8: Offset of "Interrupt" routine
  39. ;----------------------------------------------------------------
  40.        DB     'I_PREFER'      ;+0Ah..+11h = Name of Driver
  41. ;                              (padded with spaces, as required)
  42. ;================================================================
  43.        PAGE
  44. ;================================================================
  45. ;                S T R A T E G Y   R O U T I N E
  46. ;
  47. ; Called by DOS to save the pointer (in ES:BX) to the Device
  48. ; Driver Request Header.
  49. ;----------------------------------------------------------------
  50. STRAT:
  51.        MOV     CS:[HDROFS],BX ;Save offset of Request Header
  52.        MOV     CS:[HDRSEG],ES ;Save segment of Request Header
  53.        RETF                   ;Return to DOS
  54. ;================================================================
  55. ; Local Data Storage...
  56. ;----------------------------------------------------------------
  57. HEADER LABEL   DWORD          ;Allow for DD reference
  58. HDROFS DW      0000           ;Seqment storage
  59. HDRSEG DW      0000           ;Offset storage
  60. TOGGLE DB      01             ;Storage for current toggle states
  61. ;                              01 = EGA Blink Bit ON
  62. ;================================================================
  63.        PAGE
  64. ;================================================================
  65. ;             I N T E R R U P T   P R O C E D U R E
  66. ;
  67. ; Called by DOS to process a driver request, as defined in the
  68. ; Request Header.  The Request Header is found at the address
  69. ; previously passed to the Strategy Routine.
  70. ;
  71. ; Request Header format:
  72. ; +00 = NUMB     Number of bytes in Request Header (byte)
  73. ; +01 = UNIT     Unit Number of this request (byte) (BLOCK)
  74. ; +02 = CMMD     Request Command Code (byte)
  75. ; +03 = STAT     Returned Status (word)
  76. ; +05 = RESRVED  Reserved by DOS (8 bytes)
  77. ; +0D = MEDIA    Media Descriptor (byte)
  78. ; +0E = ADDR     Data Transfer Address (word:word)
  79. ; +12 = COUNT    Byte or sector count (word)
  80. ; +14 = SECT     Starting sector value (BLOCK DEVICE)
  81. ;================================================================
  82. ;       I _ P R E F E R   I N T E R R U P T   L O G I C
  83. ;----------------------------------------------------------------
  84. INTRPT:
  85.        PUSH    AX             ;Save the entry registers...
  86.        PUSH    BX
  87.        PUSH    CX
  88.        PUSH    DX
  89.        PUSH    ES
  90.        PUSH    DI
  91.        PUSH    SI
  92. ;----------------------------------------------------------------
  93. ; Retrieve the address of the Request Header and get the CMMD.
  94. ;----------------------------------------------------------------
  95.        PUSH    CS
  96.        POP     DS
  97.        LES     BX,CS:[HEADER] ;ES:BX = [HDRSEG:HDROFS]
  98.        MOV     AL,ES:[BX+02]  ;CMMD = HDRSEG:[HDROFS+2]
  99. ;----------------------------------------------------------------
  100. ; If CMMD IS "Write" or "Write with Verify", go to the "WRITE"
  101. ; logic.
  102. ;----------------------------------------------------------------
  103.        CMP    AL,08h          ;If CMMD = "WRITE" then...
  104.        JZ     WRITE           ;...WRITE
  105.        CMP    AL,09h          ;If CMMD = "WRITEV" then...
  106.        JZ     WRITE           ;...WRITE
  107. ;----------------------------------------------------------------
  108. ; If CMMD IS "INIT," go to the Initialization logic.
  109. ;----------------------------------------------------------------
  110.        CMP    AL,00           ;If CMMD = "INIT" then...
  111.        JMP    INIT            ;...INITIALIZE
  112. ;----------------------------------------------------------------
  113.        PAGE
  114. ;----------------------------------------------------------------
  115. ; For any other CMMD, return an error code in the STATUS
  116. ; parameter and return to DOS.
  117. ;----------------------------------------------------------------
  118. BADRTN:
  119.        MOV     Word Ptr ES:[BX+03],8103h
  120.        JMP     RETURN         ;Return
  121.        NOP
  122. ;----------------------------------------------------------------
  123. ; Return through here when done
  124. ;----------------------------------------------------------------
  125. GUDRTN:
  126.        MOV    Word Ptr ES:[BX+03],0100h
  127. ;----------------------------------------------------------------
  128. ; Restore registers and return to DOS
  129. ;----------------------------------------------------------------
  130. RETURN:
  131.        POP     SI             ;Restore the entry registers...
  132.        POP     DI
  133.        POP     ES
  134.        POP     DX
  135.        POP     CX
  136.        POP     BX
  137.        POP     AX
  138.        RETF                   ;Return (Far)
  139. ;================================================================
  140.        PAGE
  141. ;================================================================
  142. ;                  W R I T E   P R O C E D U R E
  143. ;
  144. ; Retrieve the "output message" for the driver.  This should be
  145. ; one character, where...
  146. ;
  147. ; ... N or n toggles the NumLock state            (Initially OFF)
  148. ; ... L or l toggles the EGA 43-line mode          (Initially ON)
  149. ; ... B or b toggles the EGA video blink state    (Initially OFF)
  150. ;================================================================
  151. WRITE:
  152.        LDS     SI,ES:[BX+0Eh] ;DS:SI = ADDR
  153.        LODSB                  ;AL = DS:[SI] = [ADDR] = "x"
  154.        PUSH    CS             ;Move CS...
  155.        POP     DS             ;...into DS
  156. ;----------------------------------------------------------------
  157. ; For [N,L,B]: Go to the appropriate "toggle" logic.
  158. ; (Otherwise, ignore the character.)
  159. ;----------------------------------------------------------------
  160.        AND     AL,5Fh         ;Make letter upper case
  161.        CMP     AL,4Eh         ;If (AL = 'N') then...
  162.        JNE     NotNum
  163.        CALL    NUMLCK         ;...CALL NUMLCK
  164.        JMP     GUDRTN
  165. NotNum:
  166.        CMP     AL,4Ch         ;If (AL = 'L') then...
  167.        JNE     NotLine
  168.        CALL    EGA43          ;...CALL EGA43
  169.        JMP     GUDRTN
  170. NotLine:
  171.        CMP     AL,42h         ;If (AL = 'B') then...
  172.        JNE     BADRTN
  173.        CALL    BLINK          ;...CALL BLINK
  174.        JMP     GUDRTN
  175. ;================================================================
  176.        PAGE
  177. ;================================================================
  178. ; NUMLCK: Toggles the NumLock State for the keyboard.
  179. ;----------------------------------------------------------------
  180. NUMLCK PROC NEAR
  181.        PUSH AX                ;Save the...
  182.        PUSH ES                ;...entry registers
  183.        MOV  AX,0040h          ;Set DS to...
  184.        MOV  ES,AX             ;...0040 (BIOS segment)
  185.        MOV  AL,Byte Ptr ES:[0017h] ;Get the keyboard state
  186.        TEST AL,20h            ;Test the NumLock bit
  187.        JNZ  NumOFF            ;
  188. NumON:
  189.        OR   AL,20h            ;If OFF, turn it ON
  190.        JMP  NumSet
  191. NumOFF:
  192.        AND  AL,0DFh           ;If ON, turn it OFF
  193. NumSet:
  194.        MOV  Byte Ptr ES:[0017h],AL ;Put it back
  195.        POP  ES                ;Restore the...
  196.        POP  AX                ;...entry registers
  197.        RET                    ;Return to the caller
  198. NUMLCK ENDP
  199. ;================================================================
  200. ; BLINK: Toggles the EGA/VGA Blink Bit
  201. ;----------------------------------------------------------------
  202. BLINK  PROC NEAR
  203.        PUSH AX                ;Save the...
  204.        PUSH BX
  205.        PUSH DS                ;...entry registers
  206.        PUSH CS
  207.        POP  DS
  208.        MOV  AL,[TOGGLE]       ;Get the current toggle word
  209.        TEST AL,01             ;Test the Blink state bit
  210.        JNZ  BlkOff
  211. BlkOn:
  212.        MOV  BL,01             ;Turn ON if currently OFF
  213.        OR   AL,01
  214.        JMP  BlkSet
  215. BlkOff:
  216.        MOV  BL,00             ;Turn OFF if currently ON
  217.        AND  AL,0FEh
  218. BlkSet:
  219.        MOV  [TOGGLE],AL
  220.        MOV  AX,1003h
  221.        INT  10h
  222.        POP  DS                ;Restore the...
  223.        POP  BX
  224.        POP  AX                ;...entry registers
  225.        RET
  226. BLINK  ENDP
  227. ;================================================================
  228.        PAGE
  229. ;================================================================
  230. ; EGA43: Toggles the 43-line mode for the EGA video.
  231. ;        (Also, sets up a block cursor, "fixes" the EGA cursor
  232. ;         emulation, and selects the EGA BIOS "Print Screen"
  233. ;----------------------------------------------------------------
  234. EGA43  PROC NEAR
  235.        PUSH AX                ;Save the...
  236.        PUSH BX
  237.        PUSH CX
  238.        PUSH ES                ;...entry registers
  239. ;----------------------------------------------------------------
  240. ; If the current BIOS screen lines count (less one) at 0040:0084
  241. ; is NOT 42, then go set up the 43-line mode.  Otherwise, restore
  242. ; the 25-line mode
  243. ;----------------------------------------------------------------
  244.        MOV  AX,0040h          ;Set DS to...
  245.        MOV  ES,AX             ;...0040 (BIOS segment)
  246.        MOV  AL,Byte Ptr ES:[0084h] ;IF (0040:0084 <> 42) then...
  247.        CMP  AL,42
  248.        JNE  GoTo43            ;...GoTo43
  249. ;----------------------------------------------------------------
  250. ; Select the 8x14 font and adjust the screen lines (to 25).
  251. ;----------------------------------------------------------------
  252. GoTo25:
  253.        MOV  AX,1111h
  254.        MOV  BL,00
  255.        INT  10h
  256. ;----------------------------------------------------------------
  257. ; Turn the EGA cursor emulation logic back on and set up a block
  258. ; cursor.  Then return.
  259. ;----------------------------------------------------------------
  260.        AND  Byte Ptr ES:[0087h],0FEh
  261.        JMP  SetCur
  262. ;----------------------------------------------------------------
  263. ; Select the 8x8 character font and adjust the screen lines
  264. ;----------------------------------------------------------------
  265. GoTo43:
  266.        MOV  AX,1112h          ;Load the 8x8 font & recalculate
  267.        MOV  BL,00             ;RAM block 0
  268.        INT  10h               ;BIOS Video Service
  269. ;----------------------------------------------------------------
  270. ; Select the alternate (EGA BIOS) Print Screen function
  271. ;----------------------------------------------------------------
  272.        MOV  BL,20h
  273.        MOV  AH,12h
  274.        INT  10h
  275. ;----------------------------------------------------------------
  276. ; Turn off the buggy EGA cursor emulation and set up a block
  277. ; cursor.  Then return.
  278. ;----------------------------------------------------------------
  279.        OR   Byte Ptr ES:[0087h],01
  280. SetCur:
  281.        MOV  CX,0007h          ;CH = Scan top; CL = Scan bottom
  282.        MOV  AH,01             ;"Set Cursor Size"
  283.        INT  10h
  284.        POP  ES                ;Restore the...
  285.        POP  CX
  286.        POP  BX
  287.        POP  AX                ;...entry registers
  288.        RET
  289. EGA43  ENDP
  290. ;================================================================
  291. RUNSIZ EQU     $-PREFERS
  292.        DB      (0100H-RUNSIZ) DUP(00)
  293. ;================================================================
  294.        PAGE
  295. ;================================================================
  296. ;            I N I T I A L I Z A T I O N   L O G I C
  297. ;================================================================
  298. ; This logic is invoked when DOS installs the driver. (CMMD = 0).
  299. ; The initialization steps include:
  300. ;
  301. ;  1. Reseting the keyboard NumLock state.
  302. ;  2. Setting the EGA video into 43-line mode
  303. ;  3. Turning off the EGA blink bit
  304. ;  4. Displaying the "I'm here!" message on the video screen.
  305. ;
  306. ; When done, the logic tells DOS where the "expendable" part of
  307. ; the driver (the initialization logic itsef) begins.  DOS will
  308. ; then release the memory AFTER that address for its own use.
  309. ;----------------------------------------------------------------
  310. INIT   LABEL   NEAR
  311.        PUSH    AX             ;Save registers
  312.        PUSH    BX             ;
  313.        PUSH    CX             ;
  314.        PUSH    DX             ;
  315.        PUSH    ES             ;
  316. ;----------------------------------------------------------------
  317. ; Call the mainline procedures to set the initial preferences.
  318. ;----------------------------------------------------------------
  319.        CALL    NUMLCK         ;Turn OFF the NumLock State
  320.        CALL    EGA43          ;Turn ON the EGA 43-line mode
  321.        CALL    BLINK          ;Turn OFF the EGA Blink bit
  322. ;----------------------------------------------------------------
  323. ; Announce the installation of the driver.
  324. ;----------------------------------------------------------------
  325.        LEA     DX,IMHERE      ;DX = Offset(IMHERE)
  326.        MOV     AH,09h         ;"Display string"
  327.        INT     21h            ;DOS service
  328. ;----------------------------------------------------------------
  329.        PAGE
  330. ;----------------------------------------------------------------
  331. ; Release the initialization logic and return.
  332. ;----------------------------------------------------------------
  333.        POP     ES             ;Restore the key entry registers
  334.        POP     DX             ;
  335.        POP     CX             ;
  336.        POP     BX             ;
  337.        LEA     AX,INIT        ;AX = Offset(INIT)
  338.        MOV     Word Ptr ES:[BX+0Eh],AX ;"ADDR" = AX
  339.        MOV     Word Ptr ES:[BX+10h],CS ;"ADDR+2" = CS
  340.        POP     AX             ;Restore AX
  341.        JMP     GUDRTN         ;Return
  342. ;================================================================
  343. IMHERE LABEL  NEAR
  344.        DB      0Dh,0Ah,'PREFERS.SYS Preferences Driver Installed.'
  345.        DB      0Dh,0Ah
  346.        DB     'Write N, L, or B to I_Prefer to change',0Dh,0Ah,'$'
  347. CSEG   ENDS
  348.        END     PREFERS
  349. ;=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  350.